using System;
using System.Collections;
using System.IO;
using System.Security.Principal;
using System.Text;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using InsightServiceUtility;
using PHSRAG.Insight21.CDS;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.InsightUtilities.Enums;
using PHSRAG.Insight21.Policy;
using PHSRAG.Security;
using PHSRAG.Utility;

namespace PHSRAG.Insight21.Humans
{
    /// <summary>
    /// The Attachments page facilitates the user specify the type of the attachment, 
    /// the title for the attachment and if the attachment is an electronic copy, 
    /// then it lets the user select the file from their hard drive and upload it to the system. 
    /// An option to specify miscellaneous attachments is also provided. 
    /// 
    /// Each attachment is scanned for viruses before being uploaded to the system.
    /// </summary>
    public partial class AttachmentsPage : BasePage
    {
        #region GridColumns Enumeration

        /// <summary>
        /// List of all columns in the grid
        /// </summary>
        private enum GridColumn
        {
            ProtocolDocId,
            DocId,
            AttachmentType,
            Title,
            AttachmentMode,
            SelectFile,
            FormsID,
            DateUploaded,
            ViewAttachment,
            MarkedForDeletion,
            IncludeWithSubmission
        }

        #endregion

        #region Constants

        /// <summary>The key for the caching mechanism that holds the ProtocolDocument objects of a Protocol version</summary>
        private const string AttachmentsKey = "AttachmentsKey_9FAD66FC-9706-476a-8A09-06B46ED46B86";

        private const string IncludeEditableKey = "AttachmentIncludeKey_6941FC68-7A8E-42c5-A2E8-874E41C40848";
        private const string PageCacheKey = "AttachmentsPage__567C6709-7008-4cce-9D77-A222F334B51F";
        private const string ProtocolAccessKey = "protocolAccessKey__567C6709-7008-4cce-9D77-A222F334B51F";
        private const string ProtocolIdKey = "protocolId__567C6709-7008-4cce-9D77-A222F334B51F";
        private const string ProtocolProcessIdKey = "protocolProcessId__567C6709-7008-4cce-9D77-A222F334B51F";
        private const string ShowAsPopupKey = "showAsPopupKey__567C6709-7008-4cce-9D77-A222F334B51F";

        #endregion

        #region Non-key Constants

        /// <summary>
        /// The constant that seperates any 2 columns in a newly added rows in the datagrid
        /// </summary>
        private const string ColSeparator = "&nbsp;";

        /// <summary>
        /// All the information in each new row added to the grid is concatenated using a ColSeperator.
        /// The following constants specify indices where a specific type of information for the newly added attachment can be found.
        /// </summary>
        private const int ColumnAttachmentType = 0;

        private const int ColumnDelete = 6;
        private const int ColumnElectronicFile = 3;
        private const int ColumnFileControlName = 7;
        private const int ColumnFilePath = 5;
        private const int ColumnHardCopy = 4;
        private const int ColumnIncludeWithSubmission = 10;
        private const int ColumnRefMeaning = 1;
        private const int ColumnTitle = 2;

        /// <summary>
        /// Name of the cover sheet
        /// </summary>
        private const string DocumentTemplatesFolder = "DocumentTemplates";

        /// <summary>
        /// The constant that seperates any 2 newly added rows in the datagrid
        /// </summary>
        private const string RowSeparator = "&crlf;";

        private const string SessionVarNameLastProtocolDocumentAscSortExpression = "LastProtocolDocumentAscSortExpression";

        #endregion Constants

        private readonly StringBuilder _errorReport = new StringBuilder();
        private ICachePolicy _applicationCachePolicy;
        private ICachePolicy _cachePolicy;
        private ArrayList _includeEditableList;
        private bool _isHardCopyChecked;
        private bool _isProtocolLocked;
        protected string _office;
        private Hashtable _pageCache;
        private ICachePolicy _pageCachePolicy;
        private Protocol _protocol;
        private ArrayList _protocolDocumentsContainer;
        private int _protocolId;
        private ProtocolProcess _protocolProcess;
        private int _protocolProcessId;
        private int _userAccessLevel;
        protected ValidationSummary _validationSummary;

        #region Private Properties

        /// <summary>
        /// Gets the protocol .If it's not already in the cache, it loads it up based on the protocolId passed to the page, and caches the object
        /// </summary>
        private Protocol Protocol
        {
            get
            {
                string cacheKey = Protocol.ProtocolKey;
                _protocol = _cachePolicy.GetCachedObject(cacheKey) as Protocol;

                if ((_protocol == null) || (_protocolId != _protocol.Id))
                {
                    _protocol = new Protocol(_cachePolicy);
                    _protocol.Load(DataAccess.GetConnectionString(), _protocolId);
                    _cachePolicy.Cache(cacheKey, _protocol);
                }
                return _protocol;
            }
        }

        /// <summary>
        /// Gets the protocol process . If it's not already
        /// in the cache, it loads it up based on the _protocolProcessId passed to the page, and caches the 
        /// object
        /// </summary>
        private ProtocolProcess ProtocolProcess
        {
            get
            {
                _protocolProcess = _cachePolicy.GetCachedObject(ProtocolProcess.ProtocolProcessKey)
                    as ProtocolProcess;

                if ((_protocolProcess == null) || (_protocolProcessId != _protocolProcess.Id))
                {
                    if (_protocolProcessId != 0)
                    {
                        _protocolProcess = ProtocolProcess.GetProtocolProcess(
                            DataAccess.GetConnectionString(), _protocolProcessId, _cachePolicy, null);
                        _cachePolicy.Cache(ProtocolProcess.ProtocolProcessKey, _protocolProcess);
                    }
                    else
                    {
                        _protocolProcess = null;
                    }
                }
                return _protocolProcess;
            }
        }

        private ArrayList IncludeEditableList
        {
            get
            {
                _includeEditableList = (ArrayList) _pageCache[IncludeEditableKey] ?? new ArrayList();

                return _includeEditableList;
            }

            set { _pageCache[IncludeEditableKey] = _includeEditableList; }
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Page Initilialization. Fetches the prevalent caching mechanisms.
        /// </summary>
        /// <param name="e">Initialization event arguments</param>
        protected override void OnInit(EventArgs e)
        {
            //
            // CODEGEN: This call is required by the ASP.NET Web Form Designer.
            //
            InitializeComponent();
            base.OnInit(e);

            _cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            _pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
            _applicationCachePolicy = (Policy.ICachePolicy) Application[Policy.Names.ApplicationCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
        }

        #endregion

        #region Events (page)

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                breadCrumb.Add(
                    "Attachments",
                    Settings.GetKeyValue("SubModuleNavigation.Humans.AttachmentsURL", ""),
                    Settings.GetKeyValue("BreadCrumb.DetailPageLevel", 2));

                _pageCache = _pageCachePolicy.GetCachedObject(PageCacheKey) as Hashtable ?? new Hashtable();


                annunciator.Message = string.Empty;

                bool showAsPopUp = false;
                if (!IsPostBack)
                {
                    Hashtable incomingPageHash =
                        _pageCachePolicy.GetCachedObject(Keys.IncomingDataKey) as Hashtable;
                    if (incomingPageHash != null)
                    {
                        _protocolId = Convert.ToInt32(incomingPageHash[Keys.ProtocolIdKey]);
                        _protocolProcessId = Convert.ToInt32(incomingPageHash[Keys.ProtocolProcessIdKey]);
                        _userAccessLevel = Convert.ToInt32(incomingPageHash[Keys.ProtocolAccessKey]);
                        if (incomingPageHash.ContainsKey(Keys.ShowAsPopUp))
                        {
                            showAsPopUp = Convert.ToBoolean(incomingPageHash[Keys.ShowAsPopUp]);
                        }

                        Protocol.Cache();
                        _pageCache[ProtocolIdKey] = _protocolId;
                        if (_protocolProcessId != 0)
                        {
                            ProtocolProcess.Cache();
                        }
                        _pageCache[ProtocolProcessIdKey] = _protocolProcessId;
                        _pageCache[ProtocolAccessKey] = _userAccessLevel;
                        _pageCache[ShowAsPopupKey] = showAsPopUp;
                        _pageCachePolicy.UnCache(Keys.IncomingDataKey);
                        _pageCachePolicy.Cache(PageCacheKey, _pageCache);
                    }
                    else
                    {
                        _protocolId = (int) _pageCache[ProtocolIdKey];
                        _protocolProcessId = (int) _pageCache[ProtocolProcessIdKey];
                        _userAccessLevel = (int) _pageCache[ProtocolAccessKey];
                        showAsPopUp = (bool) _pageCache[ShowAsPopupKey];
                        _protocol = new Protocol(_cachePolicy);
                        _protocol = (Protocol) _cachePolicy.GetCachedObject(_protocol.CacheKey());
                        if (_protocolProcessId != 0)
                        {
                            _protocolProcess = new ProtocolProcess(_cachePolicy);
                            _protocolProcess = (ProtocolProcess) _cachePolicy.GetCachedObject(_protocolProcess.CacheKey());
                        }
                    }

                    _protocolDocumentsContainer = _protocolProcessId != 0 ? _protocolProcess.ProtocolDocuments : _protocol.ProtocolDocuments;

                    allProtocolDocumentNames.Value = _protocol.ProtocolDocumentNames;
                    _isProtocolLocked = (_protocolProcess != null) ? _protocolProcess.Locked : _protocol.IsLocked;

                    if (_includeEditableList == null)
                    {
                        _includeEditableList = _protocol.IncludeEditableList;
                    }
                    IncludeEditableList = _includeEditableList;

                    if (_protocolProcess != null && (_protocolProcess.Type == Constants.ProtocolProcessType.InitialReview || _protocolProcess.Type == Constants.AnimalProtocolProcessType.InitialReview))
                    {
                        attachmentsDetail.Columns[ColumnIncludeWithSubmission].Visible = false;
                    }

                    GridBind();


                    //Attachment Types
                    string moduleType = Protocol.ModuleType;
                    RefCodes refCodes = (RefCodes) _applicationCachePolicy.GetCachedObject(RefCodes.CacheKey);

                    ArrayList attachmentRefCode;
                    if (moduleType == Constants.ModuleType.Animals)
                    {
                        // sort by a specific order
                        attachmentRefCode = refCodes.GetSortedRefCodes(FormsManagement.Constants.AttachmentType.Domain,
                            FormsManagement.Constants.AttachmentType.AnimalsOrderAttribute);
                    }
                    else
                    {
                        // sort alpha by meaning
                        attachmentRefCode = refCodes.GetSortedRefCodes(FormsManagement.Constants.AttachmentType.Domain,
                            RefCodes.RefCodeColumns.RefMeaning);
                    }

                    string attachmentTypes = "0| <-- Select Type --> ^";
                    for (int i = 0; i < attachmentRefCode.Count; ++i)
                    {
                        RefCode refCode = (RefCode) attachmentRefCode[i];

                        if (Constants.ModuleType.Animals == moduleType)
                        {
                            if ("Y" != refCode[FormsManagement.Constants.AttachmentType.AnimalsAttribute])
                            {
                                continue;
                            }
                        }
                        else // Constants.ModuleType.Humans == moduleType
                        {
                            if ("Y" != refCode[FormsManagement.Constants.AttachmentType.HumansAttribute])
                            {
                                continue;
                            }
                        }

                        attachmentTypes = attachmentTypes + refCode.Code + "|" + refCode.Meaning + "^";
                    }

                    attachmentTypesList.Value = attachmentTypes.Substring(0, attachmentTypes.Length - 1);
                    updateUploadAttachments.Attributes.Add("OnClick", "javascript:return SaveNewRowsInformation();");

                    // Remove any sort expression from previous pageloads of same session
                    Session.Remove(SessionVarNameLastProtocolDocumentAscSortExpression);
                }
                else
                {
                    showAsPopUp = (bool) _pageCache[ShowAsPopupKey];
                    _userAccessLevel = (int) _pageCache[ProtocolAccessKey];
                    _protocolId = (int) _pageCache[ProtocolIdKey];
                    _protocol = new Protocol(_cachePolicy);
                    _protocol = (Protocol) _cachePolicy.GetCachedObject(_protocol.CacheKey());

                    _protocolProcessId = (int) _pageCache[ProtocolProcessIdKey];
                    if (_protocolProcessId != 0)
                    {
                        _protocolProcess = new ProtocolProcess(_cachePolicy);
                        _protocolProcess = (ProtocolProcess) _cachePolicy.GetCachedObject(_protocolProcess.CacheKey());
                        _protocolDocumentsContainer = _protocolProcess.ProtocolDocuments;
                    }
                    else
                    {
                        _protocolDocumentsContainer = _protocol.ProtocolDocuments;
                    }
                    _isProtocolLocked = (_protocolProcess != null) ? _protocolProcess.Locked : _protocol.IsLocked;

                    //when a new version is added, the grid should be rebound and hence this page is refreshed and in such a case postBackGuard is invalid
                    object newVersionUploaded = _cachePolicy.GetCachedObject(Keys.NewVersionUploadedKey);
                    if (newVersionUploaded != null && Convert.ToBoolean(newVersionUploaded))
                        //if (!postbackGuard.ValidateAttachment)
                    {
                        _cachePolicy.UnCache(Keys.NewVersionUploadedKey);
                        GridBind();
                    }
                }

                //store the no. of rows in the grid in the hidden field
                attachmentsRowCount.Value = _protocolDocumentsContainer.Count.ToString();

                if (!_isProtocolLocked)
                {
                    downloadCoverSheet.Attributes.Add("onclick", "javascript: if (isGridDirty) return confirm('Changes will be lost if the Save button is not clicked. Press OK to continue.'); return true;");
                }

                // set the header's protocol details.	
                protocolDetailHeader.ProtocolID = _protocolId;
                //Set the Human sub mod Navigation links
                humansSubModuleNavigation.Protocol = _protocol;
                humansSubModuleNavigation.ProtocolProcess = _protocolProcess;

                //if page is being shown as popup, then hide the header section
                headerSection.Visible = !showAsPopUp;

                SetupPageForModuleType();
            }
            catch (Exception ex)
            {
                ExceptionReport.WriteToEventLog("Attachments.OnPageLoad(): Failed to load the page", ex, true, ExceptionReport.ReportType.Error);
                annunciator.Message = "Failed to load the page";
            }
        }

        /// <summary>
        /// Make necessary changes to page for use by Animals or Humans
        /// </summary>
        protected void SetupPageForModuleType()
        {
            if (Protocol.ModuleType == Constants.ModuleType.Animals)
            {
                animalsSubModuleNavigation.Visible = true;
                humansSubModuleNavigation.Visible = false;
                animalsSubModuleNavigation.ProtocolProcess = ProtocolProcess;
                animalsSubModuleNavigation.Protocol = Protocol;
                animalsSubModuleNavigation.SelectedLink = "Attachments";
                _office = "SRAC office";
                phrcLinkForTemplates.Visible = false;
            }
            else
            {
                humansSubModuleNavigation.Visible = true;
                animalsSubModuleNavigation.Visible = false;
                humansSubModuleNavigation.ProtocolProcess = ProtocolProcess;
                humansSubModuleNavigation.Protocol = Protocol;
                humansSubModuleNavigation.SelectedLink = "Attachments";
                _office = "PHRC";
                phrcLinkForTemplates.Visible = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_PreRender(object sender, EventArgs e)
        {
            //if any of the attachment types is a hardcopy, then display the cover sheet section
            hardCopyCoverSheetSection.Visible = _isHardCopyChecked;

            //Also in Datagrid PreRender
            if (_isProtocolLocked || !((_userAccessLevel & Protocol.ManagePermission) > 0 ||
                (_userAccessLevel & Protocol.EditPermission) > 0))
            {
                addNewAttachment = (HtmlInputImage) FindControl("addNewAttachment");
                addNewAttachment.Visible = false;
                updateUploadAttachments.Visible = false;
            }

            SyncInstructionBlockIds.Value = helpContainer.FindControl("helpInitNote").ClientID;
        }

        #endregion

        #region Events (controls)

        /// <summary>
        /// Resets the subnavigation selected link before the breadCrumb performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnBreadCrumbNavigate(object sender, CommandEventArgs e)
        {
            try
            {
                humansSubModuleNavigation.Reset();
                ClearProtocolDocuments();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Resets the subnavigation selected link before the header or the breadCrumb performs a redirect.
        /// </summary>
        /// <param name="sender">Control which rasied the event.</param>
        /// <param name="e">Arguments associated with the event.</param>
        protected void OnNavigate(object sender, CommandEventArgs e)
        {
            try
            {
                humansSubModuleNavigation.Reset();
                ClearProtocolDocuments();
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// Constructs and caches a hashtable of data for use by the page to which nagivation leads
        /// </summary>
        protected void OnHumansSubModNavigate(object sender, EventArgs e)
        {
            OnHumansSubModNavigate();
        }

        /// <summary>
        /// Constructs and caches a hashtable of data for use by the page to which nagivation leads
        /// </summary>
        protected void OnHumansSubModNavigate()
        {
            try
            {
                ClearProtocolDocuments();
                Hashtable outgoingData = new Hashtable();
                outgoingData.Add(Keys.ProtocolIdKey, _protocolId);
                outgoingData.Add(Keys.ProtocolAccessKey, _userAccessLevel);
                outgoingData.Add(Keys.ProtocolProcessIdKey, _protocolProcessId);
                _pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);
            }
            catch (Exception ex)
            {
                DisplayExceptionReport(ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnAttachmentsDetailItemDataBound(object sender, DataGridItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                ProtocolDocument currentPD = (ProtocolDocument) _protocolDocumentsContainer[e.Item.ItemIndex];
                int docId = currentPD.DocumentId;
                //update the hidden field to hold all the protocol document titles listed in the grid
                listedProtocolDocumentNames.Value += currentPD.Name + "@" + currentPD.Type + "|";
                //Retrieving all the controls in the current row of the grid
                Image requiredImage = (Image) e.Item.FindControl("requiredImage");
                TextBox attachmentTitle = (TextBox) e.Item.FindControl("attachmentTitle");
                Label lblTitle = (Label) e.Item.FindControl("lblTitle");
                LinkButton lnkTitle = (LinkButton) e.Item.FindControl("lnkTitle");
                CheckBox attachmentElectronic = (CheckBox) e.Item.FindControl("attachmentElectronic");
                CheckBox attachmentHardCopy = (CheckBox) e.Item.FindControl("attachmentHardCopy");
                //HtmlInputFile attachedFile = (HtmlInputFile)e.Item.FindControl("attachedFile");
                Label attachmentDateUploaded = (Label) e.Item.FindControl("attachmentDateUploaded");
                ImageButton viewAttachment = (ImageButton) e.Item.FindControl("viewAttachment");
                CheckBox attachmentMarkForDelete = (CheckBox) e.Item.FindControl("attachmentMarkForDelete");
                CheckBox attachmentIncludeWithSubmission = (CheckBox) e.Item.FindControl("attachmentIncludeWithSubmission");
                Label ameNumber = (Label) e.Item.FindControl("ameNumber");
                //Set the name attribute to the client id
                HtmlGenericControl uploadControlFrame = e.Item.FindControl("uploadControlFrame") as HtmlGenericControl;
                Label attachedFileName = (Label) e.Item.FindControl("attachedFileName");
                if (uploadControlFrame != null)
                {
                    uploadControlFrame.Attributes["name"] = uploadControlFrame.ClientID;
                    //uploadControlFrame.Attributes["onload"] = "adjustIFrameSize('" + uploadControlFrame.ClientID + "');";
                }

                //Display image(required) if the attachment is required
                bool isRequired = currentPD.Required;
                requiredImage.Visible = isRequired;

                //events for ElectronicFile and HardCopy checkboxes
                if (attachmentElectronic != null && attachmentHardCopy != null)
                {
                    attachmentElectronic.Attributes.Add("OnClick",
                        "javascript:ToggleControlsForElectronicFile('" + attachmentElectronic.ClientID + "', '" + attachmentHardCopy.ClientID + "','" + uploadControlFrame.ClientID + "')");
                    attachmentHardCopy.Attributes.Add("OnClick",
                        "javascript:ToggleControlsForHardCopy('" + attachmentHardCopy.ClientID + "', '" + attachmentElectronic.ClientID + "','" + uploadControlFrame.ClientID + "')");

                    if (attachmentHardCopy.Checked)
                    {
                        _isHardCopyChecked = true;
                    }
                }

                //check if the DateTime value is set to MinValue. If so, dont display the date
                DateTime dateUploaded = currentPD.DateReceived;
                attachmentDateUploaded.Text = dateUploaded == DateTime.MinValue ? "" : dateUploaded.ToShortDateString();

                // format the filetitle if it is too long that may expand the page out of range 
                if (currentPD.FileName != null)
                {
                    FormatFileTitle(currentPD.FileName, attachedFileName);
                }

                //Setting the grid columns based on the whether or not the protocoldocument is versioned and whether or not the protocol is locked
                if (currentPD.Version == 1 && currentPD.IsReplaceable)
                {
                    //The title can only be edited if the ProtocolDocument was not part of any submission irrespective of the status of the ProtocolProcess
                    //=> For the title field to be modifiable, ProtocolDocument's Version is 1 and ProtocolDocument is replaceable
                    //Note: A ProtocolDocument can be replaceable but still
                    //could have a version greater than 1. This scenario occurs as follows:
                    //1. User uploads a document and submits the protocol
                    //2. The protocol is unlocked for some modification
                    //	 At this point the document attached in step 1 is not replaceable but the version is still 1
                    attachmentTitle.Visible = true;
                    attachmentTitle.Attributes["onkeypress"] = "javascript:SetGridDirty();";
                    lblTitle.Visible = false;
                    lnkTitle.Visible = false;
                    if (attachmentTitle.Text.Contains("Protocol Summary") || attachmentTitle.Text.Contains("Detailed Protocol"))
                        attachmentTitle.Enabled = false;

                    String path = currentPD.FileName;
                    if (!string.IsNullOrEmpty(path))
                    {
                        uploadControlFrame.Visible = false;
                        attachmentElectronic.Enabled = false;
                        attachmentHardCopy.Enabled = false;
                        viewAttachment.Visible = true;
                        viewAttachment.ImageUrl = SetIcon(path);
                    }
                    else
                    {
                        uploadControlFrame.Visible = true;
                        attachmentElectronic.Enabled = true;
                        attachmentHardCopy.Enabled = true;
                        viewAttachment.Visible = false;
                    }
                }
                else
                {
                    //if the document has versions or is not added by the current process
                    attachmentTitle.Visible = false;
                    lblTitle.Visible = false;
                    lnkTitle.Visible = true;
                    String path = currentPD.FileName;
                    uploadControlFrame.Visible = false;
                    attachmentElectronic.Enabled = false;
                    attachmentHardCopy.Enabled = false;
                    if (!string.IsNullOrEmpty(path))
                    {
                        viewAttachment.Visible = true;
                        viewAttachment.ImageUrl = SetIcon(path);
                    }
                    else
                    {
                        viewAttachment.Visible = false;
                    }
                }

                ameNumber.Text = currentPD.ProcessName;

                if (!_isProtocolLocked)
                {
                    viewAttachment.Attributes.Add("onclick", "javascript: if (isGridDirty) return confirm('Changes will be lost if the Save button is not clicked. Press OK to continue.'); return true;");
                }

                //For CR, OE and AE, the user can add new attachments but cannot edit existing ones
                if (_isProtocolLocked || !((_userAccessLevel & Protocol.ManagePermission) > 0 ||
                    (_userAccessLevel & Protocol.EditPermission) > 0) ||
                        (ProtocolProcess != null && (ProtocolProcess.Type == Constants.ProtocolProcessType.ContinuingReview ||
                            ProtocolProcess.Type == Constants.ProtocolProcessType.OtherEvent ||
                                ProtocolProcess.Type == Constants.ProtocolProcessType.AdverseEvent) && (ProtocolProcess.Id != currentPD.AddedProtocolProcessId || currentPD.Version > 1)))
                {
                    attachmentTitle.Enabled = false;
                    attachmentElectronic.Enabled = false;
                    attachmentHardCopy.Enabled = false;
                    uploadControlFrame.Disabled = true;
                    attachmentMarkForDelete.Enabled = false;
                }


                // handle include with submission control data
                if (_protocolProcessId == currentPD.AddedProtocolProcessId)
                {
                    attachmentIncludeWithSubmission.Checked = true;

                    if (!IncludeEditableList.Contains(currentPD.Id))
                    {
                        attachmentIncludeWithSubmission.Enabled = false;
                    }

                    currentPD.IncludeWithSubmission = true;
                }
                //Remove PostBack when user clicks on attached document

                ImageButton imgAttachment = (ImageButton) e.Item.FindControl("viewAttachment");
                if (imgAttachment.Visible)
                {
                    imgAttachment.OnClientClick = "javascript:window.open('../Research/DownloadForm.aspx?Report=attachments&DocId=" + docId + "', 'ViewFile', 'resizable=yes, status=yes, scrollbars=yes');return false;";
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnAttachmentsDetailPreRender(object sender, EventArgs e)
        {
            if (_protocolDocumentsContainer.Count > 0)
            {
                //If there is a path specified for any of the attachments, then show DateUploaded and View Attachment columns 
                //and store this information in a hidden field
                //The hidden field value will be used while adding new rows to the grid
                dateUploadedColumnVisible.Value = "false";
                attachmentsDetail.Columns[(int) GridColumn.DateUploaded].Visible = false;
                attachmentsDetail.Columns[(int) GridColumn.ViewAttachment].Visible = false;
                for (int i = 0; i < _protocolDocumentsContainer.Count; ++i)
                {
                    string filePath = ((ProtocolDocument) _protocolDocumentsContainer[i]).FileName;
                    if (!string.IsNullOrEmpty(filePath))
                    {
                        attachmentsDetail.Columns[(int) GridColumn.DateUploaded].Visible = true;
                        attachmentsDetail.Columns[(int) GridColumn.ViewAttachment].Visible = true;
                        dateUploadedColumnVisible.Value = "true";
                        break;
                    }
                }

                //If protocol is locked then hide the Mark For Deletion column and store this value in the hidden field.
                //The hidden field value will be used while adding new rows to the grid
                if (_isProtocolLocked) // && _protocolProcessId == 0
                {
                    deleteColumnVisible.Value = "false";
                    attachmentsDetail.Columns[(int) GridColumn.MarkedForDeletion].Visible = false;
                    attachmentsDetail.Columns[(int) GridColumn.IncludeWithSubmission].Visible = false;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        protected void OnAttachmentsDetailItemCommand(object source, DataGridCommandEventArgs e)
        {
            if (!postbackGuard.IsValid)
            {
                return;
            }
            //Cache the ProtocolDocument corresponding to the link on which the user clicks. 
            //Register a script that will pop up a new window and loads the downloadform.aspx
            //The downloadform displays the file represented by the cached protocolDocument
            Hashtable outgoingData = new Hashtable();
            outgoingData[Keys.ProtocolProcessKey] = _protocolProcess;
            outgoingData[Keys.ProtocolAccessKey] = _userAccessLevel;
            _pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);

            /* if (e.CommandName == "ImageClick")
            {
                
                outgoingData[Keys.DocumentKey] = ((ProtocolDocument)_protocolDocumentsContainer[e.Item.ItemIndex]).ElectronicFile;
                //Script for popup window that displays the attachment
                string script = "\n<script language=JavaScript id='DisplayAttachment'>\n" +
                                "var confirmWin = null; \n" +
                                "confirmWin = window.open('DownloadForm.aspx', 'ViewFile', 'resizable=yes, status=yes, scrollbars=yes'); \n" +
                                "</script>";

                //Check whether the script is already registered
                if (!this.ClientScript.IsClientScriptBlockRegistered("DisplayAttachment"))
                {
                    //Register the script
                    this.ClientScript.RegisterClientScriptBlock(GetType(), "DisplayAttachment", script);
                }
            }*/
            if (e.CommandName == "LinkClick")
            {
                outgoingData[Keys.ProtocolDocumentKey] = (_protocolDocumentsContainer[e.Item.ItemIndex]);
                //Script for popup window that displays the attachment versions
                string script = "\n<script language=JavaScript id='AttachmentVersions'>\n" +
                    "var confirmWin = null; \n" +
                        "confirmWin = window.open('AttachmentVersions.aspx', 'AttachmentVersions', 'width=800, height=600, status=yes, toolbar=no, scrollbars=yes, resizable=yes'); \n" +
                            "</script>";

                //Check whether the script is already registered
                if (!ClientScript.IsClientScriptBlockRegistered("AttachmentVersions"))
                {
                    //Register the script
                    ClientScript.RegisterClientScriptBlock(GetType(), "AttachmentVersions", script);
                }
            }
            GridBind();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnUpdateUploadAttachmentsClick(object sender, ImageClickEventArgs e)
        {
            if (!postbackGuard.IsValid)
            {
                return;
            }
            if (!_isProtocolLocked)
            {
                UpdateDetails();
            }
            GridBind();

            //store the no. of rows in the grid in the hidden field
            attachmentsRowCount.Value = _protocolDocumentsContainer.Count.ToString();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void OnDownloadCoverSheetClick(object sender, ImageClickEventArgs e)
        {
            //form a ProtocolDocument for the cover sheet, cache it and register a script that will open a popup and load downloadform.aspx
            //The downloadform will display the file represented by the ProtocolDocument

            Hashtable outgoingData = new Hashtable();

            ProtocolDocument coverSheet = new ProtocolDocument(_pageCachePolicy);
            coverSheet.ElectronicFile = new Document(_pageCachePolicy);
            if (header.ModuleName == InsightUtilities.Constants.Modules.Humans)
            {
                coverSheet.ElectronicFile.Name = Settings.GetKeyValue("Humans.Attachments.CoverSheet", string.Empty);
            }
            else if (header.ModuleName == InsightUtilities.Constants.Modules.Animals)
            {
                coverSheet.ElectronicFile.Name = Settings.GetKeyValue("Animals.Attachments.CoverSheet", string.Empty);
            }

            try
            {
                string path = Server.MapPath("attachments.aspx.cs");
                path = path.Replace("Research\\attachments.aspx.cs", DocumentTemplatesFolder);
                FileStream fs = new FileStream(Path.Combine(path, coverSheet.ElectronicFile.Name), FileMode.Open, FileAccess.Read);
                byte[] data = new byte[fs.Length];
                fs.Read(data, 0, Convert.ToInt32(fs.Length));
                fs.Close();
                coverSheet.ElectronicFile.Blob = data;
            }
            catch (Exception ex)
            {
                ExceptionReport.WriteToEventLog("Attachments.OnDownloadCoverSheetClick(): Failed to download cover sheet", ex, true, ExceptionReport.ReportType.Error);
                annunciator.Message = "Failed to download cover sheet";
                return;
            }
            outgoingData[Keys.DocumentKey] = coverSheet.ElectronicFile;
            _pageCachePolicy.Cache(Keys.IncomingDataKey, outgoingData);
            //Script for popup window
            string script = "\n<script language=JavaScript id='DisplayAttachment'>\n" +
                "var confirmWin = null; \n" +
                    "confirmWin = window.open('DownloadForm.aspx', 'ViewFile', 'resizable=yes, status=yes, toolbar=no, menubar=yes, scrollbars=yes'); \n" +
                        "</script>";

            //Check whether the script is already registered
            if (!ClientScript.IsClientScriptBlockRegistered("DisplayAttachment"))
            {
                //Register the script
                ClientScript.RegisterClientScriptBlock(GetType(), "DisplayAttachment", script);
            }
            _isHardCopyChecked = true;
            GridBind();
        }

        /// <summary>
        /// Called when attachments detail grid is being sorted.
        /// </summary>
        /// <param name="source">The source.</param>
        /// <param name="e">The <see cref="System.Web.UI.WebControls.DataGridSortCommandEventArgs"/> instance containing the event data.</param>
        protected void OnAttachmentsDetailSort(object source, DataGridSortCommandEventArgs e)
        {
            SortOrder sortOrder;

            if ((Session[SessionVarNameLastProtocolDocumentAscSortExpression] != null) &&
                (Session[SessionVarNameLastProtocolDocumentAscSortExpression].ToString() == e.SortExpression))
            {
                sortOrder = SortOrder.Desc;
                Session.Remove(SessionVarNameLastProtocolDocumentAscSortExpression);
            }
            else
            {
                sortOrder = SortOrder.Asc;
                Session[SessionVarNameLastProtocolDocumentAscSortExpression] = e.SortExpression;
            }

            switch ((ProtocolDocumentSortByType) Enum.Parse(typeof (ProtocolDocumentSortByType), e.SortExpression))
            {
                case ProtocolDocumentSortByType.Type:
                    _protocolDocumentsContainer.Sort(new ProtocolDocumentComparer(sortOrder, ProtocolDocumentSortByType.Type));
                    break;
                case ProtocolDocumentSortByType.Name:
                    _protocolDocumentsContainer.Sort(new ProtocolDocumentComparer(sortOrder, ProtocolDocumentSortByType.Name));
                    break;
                case ProtocolDocumentSortByType.ProcessName:
                    _protocolDocumentsContainer.Sort(new ProtocolDocumentComparer(sortOrder, ProtocolDocumentSortByType.ProcessName));
                    break;
                case ProtocolDocumentSortByType.DateReceived:
                    _protocolDocumentsContainer.Sort(new ProtocolDocumentComparer(sortOrder, ProtocolDocumentSortByType.DateReceived));
                    break;
            }

            GridBind();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Seperates each value from the concatenated list of values
        /// </summary>
        /// <param name="allValues">Concatenated string holding all the newly added information, delimited by specified Seperator</param>
        /// <param name="separator">seperator constant</param>
        /// <returns></returns>
        private string[] GetValues(string allValues, string separator)
        {
            //find no. of concatenated values
            int count = 0;
            int allValuesIndex = 0;

            while (allValuesIndex < allValues.Length)
            {
                int index = allValues.IndexOf(separator, allValuesIndex);
                if (index >= 0)
                {
                    ++count;
                    allValuesIndex = index + separator.Length;
                }
            }

            //seperate values
            string[] values = new string[count];
            int startIndex = 0;

            for (int i = 0; i < values.Length; ++i)
            {
                int endIndex = allValues.IndexOf(separator, startIndex);
                if (endIndex > 0)
                {
                    values[i] = allValues.Substring(startIndex, endIndex - startIndex);
                    startIndex = endIndex + separator.Length;
                }
            }

            return values;
        }

        /// <summary>
        /// Updates all the changes made in the attachments grid to the container.
        /// 
        /// If documents are marked for deletion, then:
        ///		a. if the protocol is never submitted (ProtocolProcess.Status = WIP) and the document is added by the current process, 
        ///			then the ProtocolDocument can be deleted.
        ///		b. if the protocol is submitted atleast once, then ProtocolDocument.RemovedProtocolProcessId is set the current ProtocolProcess Id.
        ///		
        /// Note:When new rows are added to the grid by the user, the grid view state does not change as the addition of rows to the grid
        /// is done using javascript. Because of this all the newly added row information is stored in a hidden field and sent to the server.
        /// This information is processed after the information that is available in the grid view stated is updated.
        /// </summary>
        private void UpdateDetails()
        {
            if (!postbackGuard.IsValid)
            {
                return;
            }
            for (int i = attachmentsDetail.Items.Count - 1; i >= 0; --i)
            {
                ProtocolDocument protocolDoc = (ProtocolDocument) _protocolDocumentsContainer[i];
                //Check if marked for deletion
                CheckBox attachmentMarkForDelete = (CheckBox) attachmentsDetail.Items[i].FindControl("attachmentMarkForDelete");
                if (attachmentMarkForDelete.Checked)
                {
                    if ((protocolDoc.Version == 1 && protocolDoc.IsReplaceable) ||
                        !_protocol.IsLocked)
                    {
                        protocolDoc.MarkForDeletion = true;
                    }
                    else
                    {
                        protocolDoc.RemovedProtocolProcessId = _protocolProcessId;
                    }
                    continue;
                }

                bool isIncludeEditable = false;

                CheckBox attachmentIncludeWithSubmission = (CheckBox) attachmentsDetail.Items[i].FindControl("attachmentIncludeWithSubmission");
                if (attachmentIncludeWithSubmission.Enabled)
                {
                    // include box checked
                    if (attachmentIncludeWithSubmission.Checked)
                    {
                        // if IncludeEditableList contain current pd id, then it has been saved previously
                        if (IncludeEditableList.Contains(protocolDoc.Id) && protocolDoc.AddedProtocolProcessId == _protocolProcessId)
                        {
                            continue;
                        }

                        ProtocolDocument newProtocolDoc = protocolDoc;

                        // new attachmentTitle is not current by default
                        newProtocolDoc.IsCurrent = false;

                        // for attachmentTitle with existing added ppid
                        if (newProtocolDoc.AddedProtocolProcessId != 0)
                        {
                            if (newProtocolDoc.AddedProtocolProcessId != _protocolProcessId) // document not for current process yet
                            {
                                newProtocolDoc.Id = 0;
                                // add current ppid to protocolDoc
                                newProtocolDoc.AddedProtocolProcessId = _protocolProcessId;

                                // save to hidden field IncludeEditable with value = true
                                isIncludeEditable = true;
                                newProtocolDoc.IncludeEditable = true;
                                newProtocolDoc.LastLockedVersion = newProtocolDoc.LastLockedVersion + 1;
                                newProtocolDoc.Save(DataAccess.ConnectionString);
                            }
                        }

                        // add current ppid to protocolDoc
                        newProtocolDoc.AddedProtocolProcessId = _protocolProcessId;
                        newProtocolDoc.IncludeEditable = false;
                        //if (_protocolProcess.Type == Constants.ProtocolProcessType.InitialReview)
                        //{
                        //    isIncludeEditable = true;
                        //    newProtocolDoc.IncrementVersion = true; 
                        //}

                        if (isIncludeEditable)
                        {
                            _includeEditableList.Add(newProtocolDoc.Id);
                            IncludeEditableList = _includeEditableList;
                        }
                    }
                    else if (_protocolProcess.Type == Constants.ProtocolProcessType.InitialReview || _protocolProcess.Type == Constants.AnimalProtocolProcessType.InitialReview)
                    {
                        protocolDoc.IsCurrent = true;
                        protocolDoc.IncludeEditable = true;
                        protocolDoc.AddedProtocolProcessId = _protocolProcessId;
                    }
                    else //include with submission is enabled but not checked
                    {
                        // if current protocol document id in Includeeditable list
                        // Removed from list, and update database    
                        if (IncludeEditableList.Contains(protocolDoc.Id) && protocolDoc.AddedProtocolProcessId == _protocolProcessId)
                        {
                            _includeEditableList.Remove(IncludeEditableList);
                            IncludeEditableList = _includeEditableList;
                            protocolDoc.MarkForDelete = true;
                            protocolDoc.ElectronicFile = null;
                            protocolDoc.Save(DataAccess.ConnectionString);
                            _protocolProcess.ProtocolDocuments = null;
                        }
                    }
                }
                AttachmentValidationStatus attachmentValidationStatus = ProtocolDocument.ValidateAttachment(Protocol.Id, protocolDoc.Type, ((TextBox)attachmentsDetail.Items[i].FindControl("attachmentTitle")).Text,true);
                if (attachmentValidationStatus.ValidationCode == Constants.ValidProtocolDocumentAttachment)
                {
                    protocolDoc.Name = ((TextBox) attachmentsDetail.Items[i].FindControl("attachmentTitle")).Text;

                
                    protocolDoc.IsHardCopy = ((CheckBox)attachmentsDetail.Items[i].FindControl("attachmentHardCopy")).Checked;

                    //Path
                    CheckBox isElec = (CheckBox)attachmentsDetail.Items[i].FindControl("attachmentElectronic");
                    if (isElec.Enabled && isElec.Checked && protocolDoc.ElectronicFile == null)
                    {
                        ProcessUploadedFile(protocolDoc);
                    }
                }
                else   // polulate error message to notify user
                {
                    _errorReport.Append(attachmentValidationStatus.ValidationMsg.Replace("#title#", "'" + ((TextBox)attachmentsDetail.Items[i].FindControl("attachmentTitle")).Text + "'").Replace("#type#", "'" + protocolDoc.RefMeaning + "'"));
                    break;
                }
            }


            //Process newly added rows
            string[] rows = GetValues(newRowsData.Value, RowSeparator);
            for (int j = 0; j < rows.Length; ++j)
            {
                string[] cols = GetValues(rows[j], ColSeparator);

               
                    if (false == bool.Parse(cols[ColumnDelete]))
                    {
                        // validate attachment
                        AttachmentValidationStatus attachmentValidationStatus = ProtocolDocument.ValidateAttachment(Protocol.Id, cols[ColumnAttachmentType], cols[ColumnTitle],false);
                        if (attachmentValidationStatus.ValidationCode == Constants.ValidProtocolDocumentAttachment)
                        {
                            ProtocolDocument newAttachmentType;
                            //TODO: add process name and type
                            if (_protocolProcess != null)
                            {
                                newAttachmentType = _protocolProcess.AddProtocolDocument(_protocolId, cols[ColumnTitle],
                                    cols[ColumnAttachmentType], cols[ColumnRefMeaning], bool.Parse(cols[ColumnHardCopy]), _protocolProcessId);
                            }
                            else
                            {
                                newAttachmentType = _protocol.AddProtocolDocument(cols[ColumnTitle],
                                    cols[ColumnAttachmentType], cols[ColumnRefMeaning], bool.Parse(cols[ColumnHardCopy]));
                            }
                            newAttachmentType.DateReceived = DateTime.MinValue;

                            newAttachmentType.LastLockedVersion = 0;

                            if (bool.Parse(cols[ColumnElectronicFile]))
                            {
                                ProcessUploadedFile(newAttachmentType);
                            }
                        }
                        else   // polulate error message to notify user
                        {
                            _errorReport.Append(attachmentValidationStatus.ValidationMsg);
                            break;
                        }
                }
                
            }
            if (_protocolProcess != null)
            {
                _protocolProcess.LastModifiedDate = DateTime.Now;
                _protocolProcess.Validated = false;
                _protocolProcess.Save(DataAccess.ConnectionString);
                _protocolProcess.ProtocolDocuments = null;
                _protocolDocumentsContainer = _protocolProcess.ProtocolDocuments;
            }
            else
            {
                _protocol.Save(DataAccess.ConnectionString);
                _protocolDocumentsContainer = _protocol.ProtocolDocuments;
            }

            allProtocolDocumentNames.Value = _protocol.ProtocolDocumentNames;

            //display errors, if any
            if (_errorReport.Length != 0)
            {
                annunciator.Message = _errorReport.ToString();
            }
        }

        /// <summary>
        /// Creates a Document object with the file posted to the server and attaches it to the protocolDocument
        /// </summary>
        /// <param name="protocolDoc">The ProtocolDocument to which the Document object should be linked</param>
        private void ProcessUploadedFile(ProtocolDocument protocolDoc)
        {
            try
            {
                //store uploaded files in a temporary location, virus scan & upload it to database 
                //& set the documentId column of the datatable
                //each file uploaded is received by FileUploadPage which stores the file in the temporary folder. 
                //the name and path are cached.
                
                string uploadDetails = _cachePolicy.GetCachedObject(string.Format("{0}|{1}", protocolDoc.Type, protocolDoc.Name)) as String;
                if (uploadDetails != null)
                {
                    string[] names = uploadDetails.Split('|');
                    string fileName = new FileInfo(names[0]).Name;
                    bool isClean = true;

                    if (bool.Parse(Settings.GetKeyValue("VirusScanner.Enable", "false")))
                    {
                        try
                        {
                            Document.ScanFileForVirus(names[1]);
                        }
                        catch (Exception ex)
                        {
                            isClean = false;
                            _errorReport.Append(string.Format("Virus scan on {0} failed.\r\nFailure Details: {1}", fileName, ex.Message));
                        }
                    }
                    if (isClean)
                    {
                        string stagingFolder = Settings.GetKeyValue("StagingFolder", string.Empty);
                        UserContext userContext = _cachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
                        string attachmentNamePrefixForStaging = string.Format("{0}_{1}_{2}", userContext.Username, _protocolId, _protocolProcessId);
                        //Eliminate the special characters that are not supported on the file system from the protocolDocument Name;
                        string newFileName = string.Format("{0}_{1}_{2}_{3}", attachmentNamePrefixForStaging,
                            protocolDoc.Type, Helper.GetFileSystemSupportedName(protocolDoc.Name), fileName);

                        try
                        {
                            WindowsImpersonationContext wic = Authenticator.ImpersonateUser(
                                Settings.GetKeyValue("ServiceAccount", "RAG29"),
                                Settings.GetKeyValue("SAPassword", "z0hcq"),
                                Authenticator.LogonType.NewCredentials, Authenticator.LogonProvider.WinNT50);

                            string newFilePath = Path.Combine(stagingFolder, newFileName);
                            if (File.Exists(newFilePath))
                            {
                                File.Delete(newFilePath);
                            }
                            File.Move(names[1], newFilePath);

                            Authenticator.RevertUser(wic);
                        }
                        catch (Exception ex)
                        {
                            ExceptionReport.WriteToEventLog("Insight", string.Format("Failed while impersonating and saving the file to a network drive: {0}", ex), ExceptionReport.ReportType.Error);
                            throw new Exception();
                        }
                        DocumentUtility docUtility = new DocumentUtility();
                        //docUtility.ConvertToPDFCompleted += new InsightServiceUtility.ConvertToPDFCompletedEventHandler(docUtility_ConvertToPDFCompleted);
                        docUtility.Timeout = Settings.GetKeyValue("InsightServiceUtilityTimeout", -1);
                        int docId = 0;
                        string folderHierarchy = ProtocolDocument.CreateFolderHierarchy(_protocol, docId, fileName);
                        string[] metaData = new string[]
                        {
                            "ProcessName", protocolDoc.ProcessName,
                            "Att_Type", protocolDoc.RefMeaning,
                            "Att_Title", protocolDoc.Name,
                            "DocName", fileName
                        };
                        docId = Settings.GetKeyValue("SaveToSharePoint", false) ?
                            (int)docUtility.SaveFileToSharepoint(DataAccess.ConnectionString, newFileName, fileName, metaData, folderHierarchy) :
                            docUtility.SaveFileToDatabase(DataAccess.ConnectionString, newFileName, fileName);
                        if (docId == -1)
                        {
                            throw new Exception("Web service returned an error");
                        }

                        Document doc = new Document(_cachePolicy);
                        doc.Load(DataAccess.ConnectionString, docId);
                        protocolDoc.ElectronicFile = doc;
                        protocolDoc.DateReceived = DateTime.Now;
                        protocolDoc.Save(DataAccess.ConnectionString);
                        protocolDoc.ElectronicFile.Blob = null;
                        if (Path.GetExtension(fileName).ToLower() != ".pdf")
                        {
                            //Update attachmentTitle id which is now available after saving document detail in database.
                            string updatedfolderHierarchy = folderHierarchy.Replace(Constants.IdPrefix, docId.ToString());
                            if (Settings.GetKeyValue("SaveToSharePoint", false))
                            {
                                docUtility.ConvertToPDFOneWayFromSharePoint(DataAccess.ConnectionString, docId, updatedfolderHierarchy);
                            }
                            else
                            {
                                docUtility.ConvertToPDFOneWay(docId, 300, DataAccess.ConnectionString);
                            }
                        }
                    }
                    else
                    {
                        throw new Exception();
                    }

                    _cachePolicy.UnCache(string.Format("{0}|{1}", protocolDoc.Type, protocolDoc.Name));
                }
                else
                {
                    throw new Exception();
                }
            }
            catch (Exception e)
            {
                //remove the protocoldocument, if its new, from the collection
                if (protocolDoc.Id == 0)
                {
                    if (_protocolProcess != null)
                    {
                        _protocolProcess.ProtocolDocuments.RemoveAt(_protocolProcess.ProtocolDocuments.Count - 1);
                    }
                    else
                    {
                        _protocol.ProtocolDocuments.RemoveAt(_protocol.ProtocolDocuments.Count - 1);
                    }
                }
                ExceptionReport.WriteToEventLog("AttachmentsPage.ProcessUploadedFile(): Failed to process the uploaded file", e, true, ExceptionReport.ReportType.Error);
                _errorReport.Append("Failed to process the uploaded file");
            }
        }

        /// <summary>
        /// Sets the image based on the file extension
        /// </summary>
        /// <param name="fileName">Name of the file</param>
        /// <returns>ImageUrl</returns>
        private string SetIcon(string fileName)
        {
            //based on the extension set the icon
            string innerHtml = string.Empty;
            string ext = Path.GetExtension(fileName).ToLower();

            switch (ext)
            {
                case ".pdf":
                    innerHtml = "../Images/pdf.gif";
                    break;
                case ".attachmentTitle":
                case ".docx":
                case ".docm":
                case ".dot":
                case ".dotx":
                case ".dotm":
                case ".rtf":
                    innerHtml = "../Images/word.jpg";
                    break;
                case ".txt":
                    innerHtml = "../Images/note.gif";
                    break;
                case ".xls":
                case ".xlsx":
                case ".xlsm":
                case ".xlt":
                case ".xltx":
                case ".xlsb":
                    innerHtml = "../Images/excel.jpg";
                    break;
                case ".ppt":
                case ".pptx":
                case ".pptm":
                case ".pot":
                case ".potx":
                case ".potm":
                    innerHtml = "../Images/powerpoint.jpg";
                    break;
                default:
                    innerHtml = "../Images/attachment.jpg";
                    break;
            }

            return innerHtml;
        }

        /// <summary>
        /// Binds the grid to the container
        /// </summary>
        private void GridBind()
        {
            //reset the hidden field holding the names of the protocol documents listed in the grid. 
            //this will be updated on ItemDataBound event
            listedProtocolDocumentNames.Value = string.Empty;

            attachmentsDetail.DataSource = _protocolDocumentsContainer;
            attachmentsDetail.DataBind();

            if (listedProtocolDocumentNames.Value.Length > 0)
            {
                listedProtocolDocumentNames.Value = listedProtocolDocumentNames.Value.Substring(0, listedProtocolDocumentNames.Value.Length - 1);
            }
        }

        /// <summary>
        /// Displays an error message on the screen to the user with the exception, and all
        /// inner exception messages.
        /// </summary>
        /// <param name="ex">The exception to report on</param>
        private void DisplayExceptionReport(Exception ex)
        {
            annunciator.Title = InsightUtilities.Constants.Annunciator.Title;
            annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
        }

        /// <summary>
        /// format file title to avaoid file name too long
        /// on mouse over the full name of the file can be seen 
        /// </summary>
        private void FormatFileTitle(string filepath, Label FileTitle)
        {
            string formattedPath = filepath;
            int fileSetLength = Convert.ToInt16(Settings.GetKeyValue("FileTitleLengthInAttachmentPage", "50"));
            if (filepath.Length > fileSetLength)
            {
                formattedPath = filepath.Substring(0, fileSetLength - 1);
                FileTitle.Text = formattedPath + "...";
            }
            else
            {
                FileTitle.Text = formattedPath;
            }
            FileTitle.Attributes["title"] = filepath;
        }

        private void ClearProtocolDocuments()
        {
            if (ProtocolProcess != null)
            {
                ProtocolProcess.ProtocolDocuments = null;
            }
            else
            {
                Protocol.ProtocolDocuments = null;
            }
        }

        #endregion
    }
}